package cn.easyutil.util.platform.wechat.pay;

import cn.easyutil.util.javaUtil.StringUtil;
import cn.easyutil.util.platform.wechat.base.WeChatPayStatus;
import cn.easyutil.util.platform.wechat.base.WeChatPayType;
import cn.easyutil.util.platform.wechat.pay.bean.*;
import cn.easyutil.util.platform.wechat.base.WeChatPayAccount;

import java.io.File;
import java.io.FileInputStream;

/**
 * 微信支付操作
 */
public class WeChatPayOperation {

    private WeChatPayAccount account;

    private WeChatPayUtil payOperation;
    String successMsg = "<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>";

    /** 退款时需要使用到的签名文件*/
    private String certPath;

    public static WeChatPayOperation build(WeChatPayAccount account){
        WeChatPayOperation operation = new WeChatPayOperation();
        operation.account = account;
        WeChatPayUtil wo = new WeChatPayUtil(account);
        operation.payOperation = wo;
        return operation;
    }

    /**
     * 设置退款签名文件路径
     * @param certPath
     */
    public void setCertPath(String certPath){
        this.certPath = certPath;
    }

    /**
     * 统一下单
     * @param type  支付类型
     * @param params    支付参数
     * @return
     */
    public WeChatPayResultBean payOrder(WeChatPayType type, WeChatPayParamsBean params){
        switch (type){
            case thePublic:
            case smallApp:{
                return payOperation.publicpay(params);
            }
            case h5:{
                return payOperation.h5pay(params);
            }
            case appp:{
                return payOperation.apppay(params);
            }
            case scann:{
                return payOperation.scannpay(params);
            }
        }
        return null;
    }


    /**
     * 查询交易订单
     * @param orderNo   商家内部订单号(非微信)
     * @return
     */
    public WeChatPayStatus queryOrder(String orderNo){
        return payOperation.query(orderNo,null);
    }

    /**
     * 企业付款到用户余额(请至官网查询注意事项)
     * @param param
     * @return
     */
    public WeChatPayToUserResultBean payToUser(WeChatPayToUserParamBean param){
        if(StringUtil.isEmpty(certPath)){
            throw new RuntimeException("未指定退款签名文件路径");
        }
        try(FileInputStream certInput = new FileInputStream(new File(certPath))){
            WeChatPayToUserResultBean result = payOperation.payToUser(param, certInput);
            return result;
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }

    /**
     * 查询企业付款至用户零钱的交易状态(请至官网查询注意事项)
     * @param orderNo
     * @return -1-支付失败   0-支付中  1-支付成功
     */
    public int queryPayToUser(String orderNo){
        if(StringUtil.isEmpty(certPath)){
            throw new RuntimeException("未指定退款签名文件路径");
        }
        try(FileInputStream certInput = new FileInputStream(new File(certPath))){
            return payOperation.queryPayToUser(orderNo, certInput);
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }

    /**
     * 请求退款
     * @param outTradeNo	支付时传给微信的订单号
     * @param totalFee	退款金额（不能大于支付金额）
     * @return	请求微信的结果
     */
    public WeChatRefundResultBean refund(String outTradeNo, String outRefundNo, int totalFee, int refundFee){
        if(StringUtil.isEmpty(certPath)){
            throw new RuntimeException("未指定退款签名文件路径");
        }
        try(FileInputStream certInput = new FileInputStream(new File(certPath))){
            return payOperation.refund(outTradeNo,outRefundNo,totalFee,refundFee,certInput);
        }catch (Exception e){
            throw new RuntimeException(e);
        }
    }

    /***
     * 微信退款回调处理类
     * @param notifyData	微信退款回调的参数
     * @return	解析后的map
     */
    public WeChatRefundResultBean refundCallback(String notifyData){
        return payOperation.parseRefundCallback(notifyData);
    }

    /**
     * 根据微信回调封装回调信息，并验证签名的正确性
     * @return
     */
    public WeChatPayCallBackParseBean payCallBack(String callBackData){
        return payOperation.getCallBackData(callBackData);
    }

    //回复微信
    public String returnSuccess(){
        return successMsg;
    }
}
